home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / diffs / gdb-4.12 / bfd / coff-go3.c next >
Encoding:
Text File  |  1994-08-05  |  13.6 KB  |  348 lines

  1. *** orig/gdb-4.12/bfd/coff-go3.c    Mon Jul 25 23:07:12 1994
  2. --- src/gdb-4.12/bfd/coff-go3.c    Mon Jul 25 23:07:44 1994
  3. ***************
  4. *** 0 ****
  5. --- 1,342 ----
  6. + /* BFD back-end for Intel 386 COFF files under go32.
  7. +    Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
  8. +    Written by Cygnus Support.
  9. + This file is part of BFD, the Binary File Descriptor library.
  10. + This program is free software; you can redistribute it and/or modify
  11. + it under the terms of the GNU General Public License as published by
  12. + the Free Software Foundation; either version 2 of the License, or
  13. + (at your option) any later version.
  14. + This program is distributed in the hope that it will be useful,
  15. + but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. + GNU General Public License for more details.
  18. + You should have received a copy of the GNU General Public License
  19. + along with this program; if not, write to the Free Software
  20. + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  21. + #include "bfd.h"
  22. + #include "sysdep.h"
  23. + #include "libbfd.h"
  24. + #include "obstack.h"
  25. + #include "coff/i386.h"
  26. + #include "coff/internal.h"
  27. + #include "libcoff.h"
  28. + static bfd_reloc_status_type coff_i386_reloc PARAMS ((bfd *abfd,
  29. +                               arelent *reloc_entry,
  30. +                               asymbol *symbol,
  31. +                               PTR data,
  32. +                               asection *input_section,
  33. +                               bfd *output_bfd,
  34. +                               char **error_message));
  35. + /* For some reason when using i386 COFF the value stored in the .text
  36. +    section for a reference to a common symbol is the value itself plus
  37. +    any desired offset.  Ian Taylor, Cygnus Support.  */
  38. + /* If we are producing relocateable output, we need to do some
  39. +    adjustments to the object file that are not done by the
  40. +    bfd_perform_relocation function.  This function is called by every
  41. +    reloc type to make any required adjustments.  */
  42. + static bfd_reloc_status_type
  43. + coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
  44. +          error_message)
  45. +      bfd *abfd;
  46. +      arelent *reloc_entry;
  47. +      asymbol *symbol;
  48. +      PTR data;
  49. +      asection *input_section;
  50. +      bfd *output_bfd;
  51. +      char **error_message;
  52. + {
  53. +   symvalue diff;
  54. +   if (output_bfd == (bfd *) NULL)
  55. +     return bfd_reloc_continue;
  56. +   if (bfd_is_com_section (symbol->section))
  57. +     {
  58. +       /* We are relocating a common symbol.  The current value in the
  59. +      object file is ORIG + OFFSET, where ORIG is the value of the
  60. +      common symbol as seen by the object file when it was compiled
  61. +      (this may be zero if the symbol was undefined) and OFFSET is
  62. +      the offset into the common symbol (normally zero, but may be
  63. +      non-zero when referring to a field in a common structure).
  64. +      ORIG is the negative of reloc_entry->addend, which is set by
  65. +      the CALC_ADDEND macro below.  We want to replace the value in
  66. +      the object file with NEW + OFFSET, where NEW is the value of
  67. +      the common symbol which we are going to put in the final
  68. +      object file.  NEW is symbol->value.  */
  69. +       diff = symbol->value + reloc_entry->addend;
  70. +     }
  71. +   else
  72. +     {
  73. +       /* For some reason bfd_perform_relocation always effectively
  74. +      ignores the addend for a COFF target when producing
  75. +      relocateable output.  This seems to be always wrong for 386
  76. +      COFF, so we handle the addend here instead.  */
  77. +       diff = reloc_entry->addend;
  78. +     }
  79. + #define DOIT(x) \
  80. +   x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
  81. +   if (diff != 0)
  82. +     {
  83. +       const reloc_howto_type *howto = reloc_entry->howto;
  84. +       unsigned char *addr = (unsigned char *) data + reloc_entry->address;
  85. +       switch (howto->size)
  86. +     {
  87. +     case 0:
  88. +       {
  89. +         char x = bfd_get_8 (abfd, addr);
  90. +         DOIT (x);
  91. +         bfd_put_8 (abfd, x, addr);
  92. +       }
  93. +       break;
  94. +     case 1:
  95. +       {
  96. +         short x = bfd_get_16 (abfd, addr);
  97. +         DOIT (x);
  98. +         bfd_put_16 (abfd, x, addr);
  99. +       }
  100. +       break;
  101. +     case 2:
  102. +       {
  103. +         long x = bfd_get_32 (abfd, addr);
  104. +         DOIT (x);
  105. +         bfd_put_32 (abfd, x, addr);
  106. +       }
  107. +       break;
  108. +     default:
  109. +       abort ();
  110. +     }
  111. +     }
  112. +   /* Now let bfd_perform_relocation finish everything up.  */
  113. +   return bfd_reloc_continue;
  114. + }
  115. + static reloc_howto_type howto_table[] = 
  116. + {
  117. +   {0},
  118. +   {1},
  119. +   {2},
  120. +   {3},
  121. +   {4},
  122. +   {5},
  123. +   HOWTO (R_DIR32,               /* type */                                 
  124. +      0,                    /* rightshift */                           
  125. +      2,                    /* size (0 = byte, 1 = short, 2 = long) */ 
  126. +      32,                    /* bitsize */                   
  127. +      false,                    /* pc_relative */                          
  128. +      0,                    /* bitpos */                               
  129. +      complain_overflow_bitfield, /* complain_on_overflow */
  130. +      coff_i386_reloc,       /* special_function */                     
  131. +      "dir32",               /* name */                                 
  132. +      true,                    /* partial_inplace */                      
  133. +      0xffffffff,            /* src_mask */                             
  134. +      0xffffffff,            /* dst_mask */                             
  135. +      false),                /* pcrel_offset */
  136. +   {7},
  137. +   {010},
  138. +   {011},
  139. +   {012},
  140. +   {013},
  141. +   {014},
  142. +   {015},
  143. +   {016},
  144. +   HOWTO (R_RELBYTE,        /* type */                                 
  145. +      0,            /* rightshift */                           
  146. +      0,            /* size (0 = byte, 1 = short, 2 = long) */ 
  147. +      8,            /* bitsize */                   
  148. +      false,            /* pc_relative */                          
  149. +      0,            /* bitpos */                               
  150. +      complain_overflow_bitfield, /* complain_on_overflow */
  151. +      coff_i386_reloc,    /* special_function */                     
  152. +      "8",            /* name */                                 
  153. +      true,            /* partial_inplace */                      
  154. +      0x000000ff,        /* src_mask */                             
  155. +      0x000000ff,        /* dst_mask */                             
  156. +      false),        /* pcrel_offset */
  157. +   HOWTO (R_RELWORD,        /* type */                                 
  158. +      0,            /* rightshift */                           
  159. +      1,            /* size (0 = byte, 1 = short, 2 = long) */ 
  160. +      16,            /* bitsize */                   
  161. +      false,            /* pc_relative */                          
  162. +      0,            /* bitpos */                               
  163. +      complain_overflow_bitfield, /* complain_on_overflow */
  164. +      coff_i386_reloc,    /* special_function */                     
  165. +      "16",            /* name */                                 
  166. +      true,            /* partial_inplace */                      
  167. +      0x0000ffff,        /* src_mask */                             
  168. +      0x0000ffff,        /* dst_mask */                             
  169. +      false),        /* pcrel_offset */
  170. +   HOWTO (R_RELLONG,        /* type */                                 
  171. +      0,            /* rightshift */                           
  172. +      2,            /* size (0 = byte, 1 = short, 2 = long) */ 
  173. +      32,            /* bitsize */                   
  174. +      false,            /* pc_relative */                          
  175. +      0,            /* bitpos */                               
  176. +      complain_overflow_bitfield, /* complain_on_overflow */
  177. +      coff_i386_reloc,    /* special_function */                     
  178. +      "32",            /* name */                                 
  179. +      true,            /* partial_inplace */                      
  180. +      0xffffffff,        /* src_mask */                             
  181. +      0xffffffff,        /* dst_mask */                             
  182. +      false),        /* pcrel_offset */
  183. +   HOWTO (R_PCRBYTE,        /* type */                                 
  184. +      0,            /* rightshift */                           
  185. +      0,            /* size (0 = byte, 1 = short, 2 = long) */ 
  186. +      8,            /* bitsize */                   
  187. +      true,            /* pc_relative */                          
  188. +      0,            /* bitpos */                               
  189. +      complain_overflow_signed, /* complain_on_overflow */
  190. +      coff_i386_reloc,    /* special_function */                     
  191. +      "DISP8",        /* name */                                 
  192. +      true,            /* partial_inplace */                      
  193. +      0x000000ff,        /* src_mask */                             
  194. +      0x000000ff,        /* dst_mask */                             
  195. +      false),        /* pcrel_offset */
  196. +   HOWTO (R_PCRWORD,        /* type */                                 
  197. +      0,            /* rightshift */                           
  198. +      1,            /* size (0 = byte, 1 = short, 2 = long) */ 
  199. +      16,            /* bitsize */                   
  200. +      true,            /* pc_relative */                          
  201. +      0,            /* bitpos */                               
  202. +      complain_overflow_signed, /* complain_on_overflow */
  203. +      coff_i386_reloc,    /* special_function */                     
  204. +      "DISP16",        /* name */                                 
  205. +      true,            /* partial_inplace */                      
  206. +      0x0000ffff,        /* src_mask */                             
  207. +      0x0000ffff,        /* dst_mask */                             
  208. +      false),        /* pcrel_offset */
  209. +   HOWTO (R_PCRLONG,        /* type */                                 
  210. +      0,            /* rightshift */                           
  211. +      2,            /* size (0 = byte, 1 = short, 2 = long) */ 
  212. +      32,            /* bitsize */                   
  213. +      true,            /* pc_relative */                          
  214. +      0,            /* bitpos */                               
  215. +      complain_overflow_signed, /* complain_on_overflow */
  216. +      coff_i386_reloc,    /* special_function */                     
  217. +      "DISP32",        /* name */                                 
  218. +      true,            /* partial_inplace */                      
  219. +      0xffffffff,        /* src_mask */                             
  220. +      0xffffffff,        /* dst_mask */                             
  221. +      false)            /* pcrel_offset */
  222. + };
  223. + /* Turn a howto into a reloc  nunmber */
  224. + #define SELECT_RELOC(x,howto) { x = howto->type; }
  225. + #define BADMAG(x) I386BADMAG(x)
  226. + #define I386 1            /* Customize coffcode.h */
  227. + #define RTYPE2HOWTO(cache_ptr, dst) \
  228. +         cache_ptr->howto = howto_table + (dst)->r_type;
  229. + /* On SCO Unix 3.2.2 the native assembler generates two .data
  230. +    sections.  We handle that by renaming the second one to .data2.  It
  231. +    does no harm to do this for any 386 COFF target.  */
  232. + #define TWO_DATA_SECS
  233. + /* For 386 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
  234. +    library.  On some other COFF targets STYP_BSS is normally
  235. +    STYP_NOLOAD.  */
  236. + #define BSS_NOLOAD_IS_SHARED_LIBRARY
  237. + /* Compute the addend of a reloc.  If the reloc is to a common symbol,
  238. +    the object file contains the value of the common symbol.  By the
  239. +    time this is called, the linker may be using a different symbol
  240. +    from a different object file with a different value.  Therefore, we
  241. +    hack wildly to locate the original symbol from this file so that we
  242. +    can make the correct adjustment.  This macro sets coffsym to the
  243. +    symbol from the original file, and uses it to set the addend value
  244. +    correctly.  If this is not a common symbol, the usual addend
  245. +    calculation is done, except that an additional tweak is needed for
  246. +    PC relative relocs.
  247. +    FIXME: This macro refers to symbols and asect; these are from the
  248. +    calling function, not the macro arguments.  */
  249. + #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)        \
  250. +   {                                \
  251. +     coff_symbol_type *coffsym = (coff_symbol_type *) NULL;    \
  252. +     if (ptr && bfd_asymbol_bfd (ptr) != abfd)            \
  253. +       coffsym = (obj_symbols (abfd)                \
  254. +              + (cache_ptr->sym_ptr_ptr - symbols));        \
  255. +     else if (ptr)                        \
  256. +       coffsym = coff_symbol_from (abfd, ptr);            \
  257. +     if (coffsym != (coff_symbol_type *) NULL            \
  258. +     && coffsym->native->u.syment.n_scnum == 0)        \
  259. +       cache_ptr->addend = - coffsym->native->u.syment.n_value;    \
  260. +     else if (ptr && bfd_asymbol_bfd (ptr) == abfd        \
  261. +          && ptr->section != (asection *) NULL)        \
  262. +       cache_ptr->addend = - (ptr->section->vma + ptr->value);    \
  263. +     else                            \
  264. +       cache_ptr->addend = 0;                    \
  265. +     if (ptr && howto_table[reloc.r_type].pc_relative)        \
  266. +       cache_ptr->addend += asect->vma;                \
  267. +   }
  268. + #include "coffcode.h"
  269. + static bfd_target *
  270. + i3coff_object_p(a)
  271. +      bfd *a;
  272. + {
  273. +   return coff_object_p(a);
  274. + }
  275. + bfd_target
  276. + #ifdef TARGET_SYM
  277. +   TARGET_SYM =
  278. + #else
  279. +   i386go32_vec =
  280. + #endif
  281. + {
  282. + #ifdef TARGET_NAME
  283. +   TARGET_NAME,
  284. + #else
  285. +   "coff-go32",            /* name */
  286. + #endif
  287. +   bfd_target_coff_flavour,
  288. +   false,            /* data byte order is little */
  289. +   false,            /* header byte order is little */
  290. +   (HAS_RELOC | EXEC_P |        /* object flags */
  291. +    HAS_LINENO | HAS_DEBUG |
  292. +    HAS_SYMS | HAS_LOCALS | WP_TEXT),
  293. +   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
  294. +   '_',                /* leading underscore */
  295. +   '/',                /* ar_pad_char */
  296. +   15,                /* ar_max_namelen */
  297. +   2,                /* minimum alignment power */
  298. +   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
  299. +      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
  300. +      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
  301. +   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
  302. +      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
  303. +      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
  304. + /* Note that we allow an object file to be treated as a core file as well. */
  305. +     {_bfd_dummy_target, i3coff_object_p, /* bfd_check_format */
  306. +        bfd_generic_archive_p, i3coff_object_p},
  307. +     {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
  308. +        bfd_false},
  309. +     {bfd_false, coff_write_object_contents, /* bfd_write_contents */
  310. +        _bfd_write_archive_contents, bfd_false},
  311. +   JUMP_TABLE(coff),
  312. +   COFF_SWAP_TABLE,
  313. + };
  314.